﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Arch.Services.ErrorHandling;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using System.ServiceModel;

namespace Arch.Intercep.CallHandlers
{
    public class ExceptionToFaultHandler : ICallHandler
    {
        [OptionalDependency]
        public IEnumerable<IExceptionToFaultHandler> ExceptionToFaultHandlers { get; set; }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            var result = getNext()(input, getNext);
            if (ExceptionToFaultHandlers != null && result.Exception != null && !(result.Exception is FaultException))
            {
                foreach (var handler in ExceptionToFaultHandlers.Where(handler => handler.Recognize(result.Exception)))
                {
                    return input.CreateExceptionMethodReturn(handler.Convert(result.Exception));
                }
                throw new InvalidOperationException("Exception not handled into a fault", result.Exception);
            }

            return result;
        }

        public int Order { get; set; }
    }
}
